/**
 * 类型守卫
 * @param strOrArray 
 * @returns 
 */
function convert1(strOrArray: string | string[]) {
    if (typeof strOrArray == 'string') {
        return strOrArray.toUpperCase()
    }
    else if (Array.isArray(strOrArray)) {
        return strOrArray.map(item => item.toUpperCase())
    }
}
console.log('convert1 "abc" is ', convert1('abc'))
console.log('convert1 "[a,abc, abcdef]" is ', convert1(['a', 'abc', 'abcdef']))

function switchConvert1(c: 'a' | 1) {
    switch (c) {
        case 'a':
            return c.toLowerCase()
        case 1:
            return c.toFixed(2)
    }
}
console.log('switchConvert1 "a" is ', switchConvert1('a'))
console.log('switchConvert1 "1" is ', switchConvert1(1))

function switchConvert2(c: {name: 'CC', sex: 'Male'} | {name: 'DD', sex: 'Female'}) {
    switch (c.name) {
        case 'CC':
            return `CC\`s sex is ${c.sex}, he is humans.`
        case 'DD':
            return `DD is a beautiful woman.`
    }
}
console.log('switchConvert2 "DD" is ', switchConvert2({name: 'DD', sex: 'Female'}))

/**
 *  typeof c 表达式的返回值类型是字面量联合类型 
 *  'string' | 'number' | 'bigint' | 
 *  'boolean' | 'symbol' | 'undefined' | 
 *  'object' | 'function'
 */
const s1 = 'abc'
console.log(typeof s1) // string
const s2 = new String('abc')
console.log(typeof s2) // object
const s3 = String('abc')
console.log(typeof s3) // string

class BigDog {
    wang = 'wangwang'
}
class Cat {
    miao = 'miaomiao'
}
function instanceOfConvert(animal: BigDog | Cat) {
    if (animal instanceof BigDog) {
        return animal.wang
    }
    if (animal instanceof Cat) {
        return animal.miao
    }
}
const cat = new Cat()
console.log('cat: ', instanceOfConvert(cat)) // miaomiao

interface InterfaceDog {
    wang: string
}
interface InterfaceCat {
    miao: string
}
function inConvert(animal: InterfaceDog | InterfaceCat) {
    if ('wang' in animal) {
        return animal.wang
    }
    if ('miao' in animal) {
        return animal.miao
    }
    // "instanceof" 表达式左侧必须是 "any" 类型、对象类型或类型参数。ts(2358)
    // if (animal instanceof InterfaceDog) {}
}

const getName1 = <T extends BigDog | Cat>(animal: T) => {
    if ('wang' in animal) {
        return animal.wang
    }
    return animal.miao
}

const getName2 = <T extends BigDog | Cat>(animal: T) => {
    if (animal instanceof BigDog) {
        return animal.wang
    }
    return animal.miao
}